#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <mysql/mysql.h>

// 定义一些常量和全局变量
#define SERVER_PORT 8888
#define BUFFER_SIZE 1024
#define MAX_CLIENTS 100
#define SQL_IP "localhost"
#define SQL_USERNAME "mxq"
#define SQL_PASSWORD "156354"
#define SQL_DATABASE "play"

// 定义客户端结构体
typedef struct 
{
    int sockfd;
    struct sockaddr_in addr;
    char username[255];
} Client;

// 定义全局变量
Client clients[MAX_CLIENTS];
pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
conn = mysql_init(NULL);

// 函数声明
void *client_handler(void *arg);
void handle_registration(int sockfd, char *username, char *password);
void handle_login(int sockfd, char *username, char *password);
void handle_ready(int sockfd);
void handle_exit(int sockfd);
void handle_game(int user1_sockfd, int user2_sockfd);
void sql_insert(MYSQL *mysql,char *sql);
void sql_select(MYSQL *mysql,char *sql);
void sql_delete(MYSQL *mysql,char *sql);

int main() 
{
	
    
    if (!mysql_real_connect(conn, SQL_IP, SQL_USERNAME, SQL_PASSWORD, SQL_DATABASE, 0, NULL, 0)) 
    {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
    
    // 初始化服务器端套接字
    int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sockfd == -1) 
    {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 绑定服务器端地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) 
    {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    // 监听客户端连接
    if (listen(server_sockfd, MAX_CLIENTS) == -1) 
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    // 接受客户端连接并创建线程处理请求
    while (1) 
    {
        int client_sockfd;
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_sockfd == -1) 
        {
            perror("accept");
            continue;
        }

        pthread_t tid;
        Client *client = (Client *)malloc(sizeof(Client));
        client->sockfd = client_sockfd;
        memcpy(&client->addr, &client_addr, client_addr_len);
        pthread_create(&tid, NULL, client_handler, client);
    }

    close(server_sockfd);
    return 0;
}

void *client_handler(void *arg) 
{
    Client *client = (Client *)arg;
    int sockfd = client->sockfd;
    char buffer[BUFFER_SIZE];

    // 处理客户端请求
    ssize_t recv_size;
    while ((recv_size = recv(sockfd, buffer, BUFFER_SIZE, 0)) > 0) 
    {
        char cmd;
        sscanf(buffer, "%c", &cmd);

        switch (cmd) 
        {
            case 'R': // 注册
                {
                    char username[32];
                    char password[32];
                    char *query;
                    re_rec:
                    read(sockfd,username,sizeof(username));
                    read(sockfd,password,sizeof(password));
                    snprintf(query, sizeof(query), "SELECT 1 FROM %s WHERE %s = '%s' LIMIT 1", "player", "usrname", username);
                    
    				// 执行SQL查询
    				if (mysql_query(conn, query)) 
    				{
        				fprintf(stderr, "%s\n", mysql_error(conn));
        				return 1;
    				}

    				// 判断结果集中是否有行
    				MYSQL_RES *res = mysql_store_result(conn);
    				if (res && mysql_num_rows(res) > 0) 
    				{
    					char *re = "The username is already in use!";
        				send(sockfd, re, sizeof(re),0);
        				goto re_rec;
    				} else 
    				{
    					handle_registration(sockfd, username, password);
        				char *re = "register_success";
        				send(sockfd, re, sizeof(re),0);
    				}
    				mysql_free_result(res);       
                }
                break;
            case 'L': // 登录
                {
                    char username[32];
                    char password[32];
                    sscanf(buffer + 1, "%s %s", username, password);
                    handle_login(sockfd, username, password);
                }
                break;
            case 'Y': // 准备
                handle_ready(sockfd);
                break;
            case 'E': // 退出
                handle_exit(sockfd);
                break;
            default:
                break;
        }
    }

    close(sockfd);
    free(client);
    return NULL;
}

void sql_insert(MYSQL *mysql,char *sql)
{
	if(mysql_real_query(mysql,sql,strlen(sql)))
	{
		printf("mysql_real_query : %s\n",mysql_error(mysql));
		return 0;
	}
}

void sql_select(MYSQL *mysql,char *sql)
{
	
}
void handle_registration(int sockfd, char *username, char *password) 
{
    // 在这里实现用户注册功能
    // 将用户信息插入MySQL数据库中的users表
    char *sql;
    sprintf(sql,"insert into player values('%s','%s',1,0,0)",username,password);
    sql_insert(conn,sql);    
    
    
}

void handle_login(int sockfd, char *username, char *password) 
{
    // 在这里实现用户登录功能
    // 1. 查询MySQL数据库中的users表，检查用户名和密码是否匹配
    // 2. 如果匹配，则将登录成功的客户端信息存入clients数组，并向客户端发送成功的消息
    // 3. 如果不匹配，则向客户端发送失败的消息
}

void handle_ready(int sockfd) 
{
    // 在这里实现用户准备功能
    // 1. 将客户端状态设置为ready
    // 2. 检查是否有其他客户端也处于ready状态，如果有则进行匹配
    // 3. 执行游戏函数handle_game
}

void handle_exit(int sockfd) 
{
    // 在这里实现用户退出登录功能
    // 1. 将客户端信息从clients数组中移除
    // 2. 向客户端发送退出成功的消息
}

void handle_game(int user1_sockfd, int user2_sockfd) 
{
    // 在这里实现游戏功能
    // 1. 对两个客户端进行3轮猜大小游戏
    // 2. 将游戏结果插入MySQL数据库中的game_results表，并更新users表中的积分
    // 3. 向两个客户端发送游戏结果
}
